/* File: DrawableOrgnaism.java
 * Purpose: This class is used to provide methods for drawing organisms.
 * Author: Team Karp
 * Date: 1/7/08
 * Revisions: 1/7/08, Ryan Bovorasmy - Initial Version
 *              [2008-02-11, Adam Patterson - Added Alpha health fade]
 *  [2008-02-15, Ryan J. Bovorasmy] Added comments (for adv. graphics report).
 * Additional Requirements: 
 */
package protovitae.engine;

// import java.nio.FloatBuffer;
import protovitae.data.ConcreteOrganism;
import protovitae.data.Organism;

import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import protovitae.data.ExposedAttribute;
import protovitae.data.Simulation;

/**
 * @author Ryan J. Bovorasmy
 * This class is used to provide methods for drawing organisms.
 */
public class DrawableOrganism extends ConcreteOrganism {

    /**
     * Constructor.
     */
    public DrawableOrganism(Simulation parentSim) {
        super(parentSim);
        id++;
    }
    
    /**
     * Copy constructor.
     * @param right
     */
    public DrawableOrganism(ConcreteOrganism right,Simulation parentSim) {
        super(right,parentSim);
        id++; //Dupe
    }

    /**
     * Draw the organism to the screen.
     * @param gl The GL object.
     * @param mode When mode == GL.GL_SELECT, the orgnaism will be drawn as a selection model.
     * @param index The index of the organism, used with selection and picking.
     * @param selected Is the organism selected?
     */
    public void render(GL gl, int mode, int index, boolean selected) {
        GLU glu = new GLU();

        double red = (double) this.getColor().getRed() / 255.0;
        double green = (double) this.getColor().getGreen() / 255.0;
        double blue = (double) this.getColor().getBlue() / 255.0;
        
        ExposedAttribute health = this.getAttribute(Organism.ATTRIBUTE_TYPE.HEALTH);
        double alpha = (double) health.getCurrent() / health.getMax();
        if(alive){
            alpha = 1.0;    //only fades after death 
        }
        
        
        gl.glColor4d(red, green, blue,alpha);

        gl.glPushAttrib(gl.GL_ENABLE_BIT | gl.GL_LIGHTING | gl.GL_CURRENT_BIT | gl.GL_POLYGON_BIT);
        gl.glColorMaterial(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT_AND_DIFFUSE);
        gl.glEnable(gl.GL_COLOR_MATERIAL); // Blue book says to call ColorMaterial before Enable
        
        gl.glPushMatrix();
        gl.glScalef(1, -1, 1);
        
        

        GLUquadric quad = glu.gluNewQuadric();

        glu.gluQuadricDrawStyle(quad, GLU.GLU_FILL);
        glu.gluQuadricNormals(quad, GLU.GLU_SMOOTH);
        double size = getSize();

        gl.glTranslated(position.getX(), position.getY(), position.getZ());
        
        if (mode == GL.GL_SELECT) {
            gl.glLoadName(index);
            glu.gluSphere(quad, size, 10, 10);
        }else{
            glu.gluSphere(quad, size, 10, 10);
        }
        
        if (selected) {
            gl.glColor3d(red, green, blue);
            gl.glBegin(GL.GL_LINE_LOOP);
            {
                for (int j = 0; j < 360; ++j) {
                    double currentRad = j * (Math.PI/180.0);
                    gl.glVertex2d(Math.cos(currentRad) * (this.getSize() + 10), 
                            Math.sin(currentRad) * (this.getSize() + 10));
                }
            }
            gl.glEnd();
            gl.glColor4d(red, green, blue, alpha);
        }
        
        glu.gluDeleteQuadric(quad);

        gl.glPopMatrix();
        gl.glPopAttrib();
    }
    

}
